import {
  Box,
  DraggableItem,
  DragHandle,
  Expandable,
  FieldCols,
  FieldEffect,
  Icon,
  mapField,
  UploadWithFilename,
  useCall,
  useDraggingCtx,
  useFieldCtx,
  useFormValue,
  useSimpleMemo,
  useToggle,
} from '@/components';
import { Button, Form, Input, Space } from 'antd';
import clsx from 'clsx';
import React, { useEffect, useMemo, useRef, useState } from 'react';
import styles from '../index.less';

const RichTextView = ({ value }) => {
  return (
    <div style={{ position: 'relative', maxHeight: 240, overflow: 'auto' }}>
      <div dangerouslySetInnerHTML={{ __html: value }} />
    </div>
  );
};

function GroupTitle({ form, defaultTitle, titleReadOnly = false }) {
  const fallbackTitle = defaultTitle || '（未命名分类）';
  const [editing, toggleEdit] = useToggle();
  const _value = form.getFieldValue(['title']) || fallbackTitle;
  const valueRef = useRef(_value);
  const [value, change] = useState(_value);

  const handleChange = useCall((e) => {
    // if (e.nativeEvent.isComposing === true) return;
    change(e.target.value);
  });

  const handleToggle = useCall(() => {
    if (titleReadOnly && !editing) return;
    if (!editing) {
      valueRef.current = value;
    } else {
      const title = value || fallbackTitle;
      form.setFieldsValue({ title });
      if (value !== title) change(title);
    }
    toggleEdit();
  });

  if (!editing) {
    return (
      <Space className={styles.titleText} size='small' direction='horizontal' onClick={handleToggle}>
        <span>{value}</span>
        {!titleReadOnly && <Icon type='edit' className={styles.titleIcon} />}
      </Space>
    );
  }

  return <Input className={styles.titleInput} value={value} onChange={handleChange} autoFocus onBlur={handleToggle} />;
}

function UpdateForm({ form, value, onChange }) {
  const state = useFormValue(form);

  useEffect(() => {
    form?.setFieldsValue(value);
  }, [value]);

  useEffect(() => {
    onChange?.(state);
  }, [state]);

  return null;
}

function InfoGroupEdit({
  draggable = false,
  value,
  onChange,
  renderFields,
  defaultTitle,
  titleReadOnly,
  disableRichText,
  disableAttachment,
  disabled = false,
  text,
  uploadProps,
}) {
  const [form] = Form.useForm();

  const dragHandle = draggable && (
    <DragHandle>
      <Button type='text' size='small'>
        <Icon type='menu' />
      </Button>
    </DragHandle>
  );
  const DragContainer = useRef((r) => <DraggableItem row={row} children={r.children} />).current;
  const Container = draggable ? DragContainer : 'div';

  const name = useFieldCtx('name');
  const row = useSimpleMemo({ id: Array.isArray(name) ? name.join('.') : name });
  const expandedControl = useDraggingCtx() ? false : null;
  const type = useFormValue(form, 'type');

  useEffect(() => {
    if (type !== '2' && disableRichText) {
      form.setFieldsValue({ type: '2' });
    } else if (type !== '1' && disableAttachment) {
      form.setFieldsValue({ type: '1' });
    }
  }, [type, disableAttachment, disableRichText]);

  const fields = useMemo(() => {
    const consistentFields = [
      type === '2' && ['list', null, UploadWithFilename, { initialValue: [], disabled, ...uploadProps }],
      type === '1' && ['richTextInfo', null, disabled ? RichTextView : 'editor'],
      text != null && ['_', null, () => <span className='c-text-secondary'>{text}</span>],
    ]
      .filter(Boolean)
      .map(mapField, { merge: { preserve: true, noStyle: true } });

    const typeField = mapField([
      'type',
      '描述类型',
      'radio-group',
      {
        initialValue: disableRichText ? '2' : '1',
        options: [
          { value: '2', label: '附件', disabled: disableAttachment && !disableRichText },
          { value: '1', label: '富文本', disabled: disableRichText },
        ],
      },
    ]);

    return (disabled || disableRichText || disableAttachment ? [] : [typeField]).concat(
      renderFields?.length ? renderFields : consistentFields,
    );
  }, [renderFields, type, disabled, disableRichText, disableAttachment]);

  return (
    <>
      <UpdateForm form={form} value={value} onChange={onChange} />
      <Container>
        <Form form={form} component={false} labelAlign='left'>
          <FieldEffect name='id' />
          {/*<FieldEffect name='isShow' />
           <FieldEffect name='showContentType' />
           <FieldEffect name='list' />*/}
          <Expandable defaultExpanded expanded={expandedControl}>
            <div className={clsx(styles.groupHeadline, { [styles.dragging]: expandedControl === false })}>
              <Box grow>
                {dragHandle}
                <GroupTitle form={form} defaultTitle={defaultTitle} titleReadOnly={titleReadOnly} />
              </Box>

              <div>
                <Expandable.Trigger />
              </div>
            </div>

            <Expandable.Content>
              <Box py={2} px={2}>
                <FieldCols
                  fields={fields}
                  rowProps={{ justify: 'center' }}
                  colProps={{ xs: 24, lg: 16 }}
                  labelSpan={4}
                  wrapperSpan={20}
                />
                <Box py={0.5} />
              </Box>
            </Expandable.Content>
          </Expandable>
          <Box py={0.5} />
        </Form>
      </Container>
    </>
  );
}

export default InfoGroupEdit;
